package main
{
	import away3d.cameras.Camera3D;
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.View3D;
	import away3d.core.base.Object3D;
	import away3d.core.clip.FrustumClipping;
	import away3d.core.render.Renderer;
	
	import flash.display.Sprite;
	import flash.display.StageQuality;
	import flash.events.Event;
	
	import gs.TweenLite;
	
	[Event(type="flash.events.Event", name="complete")]
	public class Scene3D extends Sprite
	{
		private static var instance:Scene3D;
		private static var instCount:int = 0;
		
		
		private var view:View3D;
		private var sceneBuilder:SceneBuilder;
		private var unscaledWidth:Number = 100;
		private var unscaledHeight:Number = 100;
		

		
		public function Scene3D(xml:XML) {
			
			view = new View3D();
			//view.clipping = new RectangleClipping();
			//view.clipping = new NearfieldClipping();
			view.clipping = new FrustumClipping();
			
			addChild(view);
			
			sceneBuilder = new SceneBuilder();
			sceneBuilder.bitmapPrecision = Conf.BITMAP_PRECISION;
			initialize(xml);
			
		}
    

		
		private function initialize(xml:XML):void {
			sceneBuilder.addEventListener(Event.COMPLETE, onSceneComplete);
			sceneBuilder.initialize(xml);

		//	view.clipping = new RectangleClipping({minX:-400,minY:-225,maxX:400,maxY:225});
			view.scene.addChild(sceneBuilder.getSceneObject());
			view.camera = new Camera3D({focus:Conf.CAMERA_FOCUS});
			
			view.renderer = Renderer.CORRECT_Z_ORDER;
			start();
		}
		
		private function onSceneComplete(e:Event):void {
			dispatchEvent(new Event(Event.COMPLETE));
		}
		
		public function findObject(name:String, node:ObjectContainer3D=null):Object3D {
			if (!node) node = view.scene;
			
			for each(var ob:Object3D in node.children) {
				if (ob.name == name) return ob;

				if (ob is ObjectContainer3D) {
					var o:Object3D = findObject(name, ob as ObjectContainer3D);
					if (o) return o;
				}
			}
			
			
			return null;
		}
		
		public function findMaterial(name:String):void {
			
		}
		
		public function changeCamera(name:String, immediate:Boolean=false):void {
			var cam:Camera3D = sceneBuilder.getCamera(name);
			if (immediate) {
				view.camera.x = cam.x;
				view.camera.y = cam.y;
				view.camera.z = cam.z;
				view.camera.rotationX = cam.rotationX;
				view.camera.rotationY = cam.rotationY;
				view.camera.rotationZ = cam.rotationZ;
				view.camera.zoom = cam.zoom;
			} else {
//				var q:Quaternion = new Quaternion();
//				q.euler2quaternion(cam.rotationX, cam.rotationY, cam.rotationZ);
				stage.quality = StageQuality.LOW;
				TweenLite.to(view.camera, Conf.CAMERA_TWEEN_TIME, {
					x:cam.x,
					y:cam.y,
					z:cam.z,
					rotationX:cam.rotationX,
					rotationY:cam.rotationY,
					rotationZ:cam.rotationZ,
					zoom:cam.zoom,
					onComplete: function():void {
						stage.quality = StageQuality.HIGH;
					}
				}
				);
				
			}
//			view.camera = sceneBuilder.getCamera(name);
		}
		
		private function start():void {
			addEventListener(Event.ENTER_FRAME, onEnterFrame);			
		}
		
		private function stop():void {
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		private function onEnterFrame(e:Event):void {
			view.render();
		}

		
		public function resize(w:Number, h:Number):void {
			unscaledWidth = w;
			unscaledHeight = h;
			if (view) {
				view.clipping.minX = -w/2;
				view.clipping.maxX = w/2;
				view.clipping.minY = -h/2;
				view.clipping.maxY = h/2; 
				view.updateScreenClipping();
				view.x = w/2;
				view.y = h/2;
			}
		}
		

	}
}